﻿using System;
using MS.InformationManagement.Core.Support;
using MS.InformationManagement.DAL.RecordCenter;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace MS.InformationManagement.BLL.TRD
{
    public class CreateTRDItemCommand : IBaseCommand
    {
        #region [Private Fields]

        private DataContext _DataContext;

        private int? _Id;

        private string _Title;
        private string _Law;
        private string _ChangeNotes;
        private string _Changes;

        private ItemTRD _Entity;
        private FondosFondo _Backdrop;
        private FondosFondo _ChildBackdrop;
        private SeccionesSeccion _Section;
        private SeccionesSeccion _Subsection;
        private Serie _Serie;
        private Subserie _Subserie;

        private double _GeneralStorageTime;
        private double _CentralStorageTime;

        private bool _ShouldBeKept;
        private bool _ShouldBeSelected;
        private bool _ShouldBeDeleted;
        private bool _ShouldBeTechnicalMean;

        private List<TipoDocumental> _DocumentTypes;

        #endregion

        #region [Constructors]

        public CreateTRDItemCommand(string title, FondosFondo backdrop, FondosFondo childBackdrop, SeccionesSeccion section
            , SeccionesSeccion subsection, Serie serie, Subserie subserie, double generalStorageTime, double centralStorageTime, bool shouldbeKept, bool shouldbeSelected
            , bool shouldbeDeleted, bool ShouldbeTechnicalMean, string law, List<TipoDocumental> documentTypes, DataContext dataContext)
        {
            _Backdrop = backdrop;
            _CentralStorageTime = centralStorageTime;
            _ChildBackdrop = childBackdrop;
            _DocumentTypes = documentTypes;
            _GeneralStorageTime = generalStorageTime;
            _Law = law;
            _Section = section;
            _Serie = serie;
            _ShouldBeDeleted = shouldbeDeleted;
            _ShouldBeKept = shouldbeKept;
            _ShouldBeSelected = shouldbeSelected;
            _ShouldBeTechnicalMean = ShouldbeTechnicalMean;
            _Subsection = subsection;
            _Subserie = subserie;
            _Title = title;

            _DataContext = dataContext;
        }

        public CreateTRDItemCommand(int? id, string title, FondosFondo backdrop, FondosFondo childBackdrop, SeccionesSeccion section
            , SeccionesSeccion subsection, Serie serie, Subserie subserie, double generalStorageTime, double centralStorageTime, bool shouldbeKept, bool shouldbeSelected
            , bool shouldbeDeleted, bool ShouldbeTechnicalMean, string law, List<TipoDocumental> documentTypes, string changeNotes, DataContext dataContext)
        {
            _Id = id;
            _Backdrop = backdrop;
            _CentralStorageTime = centralStorageTime;
            _ChangeNotes = changeNotes;
            _ChildBackdrop = childBackdrop;
            _DocumentTypes = documentTypes;
            _GeneralStorageTime = generalStorageTime;
            _Law = law;
            _Section = section;
            _Serie = serie;
            _ShouldBeDeleted = shouldbeDeleted;
            _ShouldBeKept = shouldbeKept;
            _ShouldBeSelected = shouldbeSelected;
            _ShouldBeTechnicalMean = ShouldbeTechnicalMean;
            _Subsection = subsection;
            _Subserie = subserie;
            _Title = title;

            _DataContext = dataContext;
        }

        #endregion

        #region [IBaseCommand Members]

        public void Execute()
        {
            if (_Backdrop != default(FondosFondo)) _DataContext.Fondos.Attach(_Backdrop);
            if (_ChildBackdrop != default(FondosFondo)) _DataContext.Fondos.Attach(_ChildBackdrop);
            _DataContext.Secciones.Attach(_Section);
            _DataContext.Secciones.Attach(_Subsection);
            _DataContext.Series.Attach(_Serie);
            _DataContext.Subseries.Attach(_Subserie);

            _Entity = new ItemTRD
            {
                Title = _Title,
                Activo = true,
                Conservación = _ShouldBeKept,
                Eliminación = _ShouldBeDeleted,
                Fondo = _Backdrop,
                Legislación = _Law,
                MedioDeConservación = _ShouldBeTechnicalMean,
                Observaciones = _ChangeNotes,
                SeccionTRD = _Section,
                Selección = _ShouldBeSelected,
                SerieTRD = _Serie,
                SubFondo = _ChildBackdrop,
                SubseccionTRD = _Subsection,
                SubserieTRD = _Subserie,
                TiempoDeRetenciónEnArchivoCentral = _CentralStorageTime,
                TiempoDeRetenciónEnArchivoGeneral = _GeneralStorageTime,

            };

            _Entity.OperaciónRealizada = !this._Id.HasValue ? "Creación de item de tabla de retención" : GetChanges();

            _Entity.TiposDocumentales = new Microsoft.SharePoint.Linq.EntitySet<TipoDocumental>();

            foreach (TipoDocumental currentDocumentType in _DocumentTypes)
            {
                _DataContext.TiposDocumentales.Attach(currentDocumentType);
                _Entity.TiposDocumentales.Add(currentDocumentType);
            }

            _DataContext.ConfiguraciónTablaDeRetenciónDocumental.InsertOnSubmit(_Entity);
            _DataContext.SubmitChanges();

            _Id = _Entity.Id.Value;
        }

        public void Undo()
        {
            if (_Entity != null)
            {
                _DataContext.ConfiguraciónTablaDeRetenciónDocumental.RecycleOnSubmit(_Entity);
                _DataContext.SubmitChanges();
            }
        }

        #endregion

        #region [Private Members]

        private string GetChanges()
        {
            StringBuilder changes = new StringBuilder();
            ItemTRD oldEntity = _DataContext.ConfiguraciónTablaDeRetenciónDocumental.SingleOrDefault(item => item.Id.Equals(_Id));
            if (oldEntity == default(ItemTRD)) { throw new Exception(string.Format("No existe un item en la lista de configuración de tablas de retención documental con el id {0}", _Id)); }

            if (_Entity.Conservación != oldEntity.Conservación) { changes.Append(LogPropertyChange("Disposición Final: Conservacion", oldEntity.Conservación, _Entity.Conservación)); }
            if (_Entity.Eliminación != oldEntity.Eliminación) { changes.Append(LogPropertyChange("Disposición Final: Eliminar", oldEntity.Eliminación, _Entity.Eliminación)); }
            if (_Entity.Fondo != oldEntity.Fondo) { changes.Append(LogPropertyChange("Fondo", oldEntity.Fondo.Title, _Entity.Fondo.Title)); }
            if (_Entity.Legislación != oldEntity.Legislación) { changes.Append(LogPropertyChange("Legislación", oldEntity.Legislación, _Entity.Legislación)); }
            if (_Entity.MedioDeConservación != oldEntity.MedioDeConservación) { changes.Append(LogPropertyChange("Disposición Final: Medio de Técnico", oldEntity.MedioDeConservación, _Entity.MedioDeConservación)); }
            if (_Entity.SeccionTRD != oldEntity.SeccionTRD) { changes.Append(LogPropertyChange("Sección", oldEntity.SeccionTRD.Title, _Entity.SeccionTRD.Title)); }
            if (_Entity.Selección != oldEntity.Selección) { changes.Append(LogPropertyChange("Disposición Final: Selección", oldEntity.Selección, _Entity.Selección)); }
            if (_Entity.SerieTRD != oldEntity.SerieTRD) { changes.Append(LogPropertyChange("Serie", oldEntity.SerieTRD.Title, _Entity.SerieTRD.Title)); }
            if (_Entity.SubFondo != oldEntity.SubFondo) { changes.Append(LogPropertyChange("Subfondo", oldEntity.SubFondo.Title, _Entity.SubFondo.Title)); }
            if (_Entity.SubseccionTRD != oldEntity.SubseccionTRD) { changes.Append(LogPropertyChange("Subsección", oldEntity.SubseccionTRD.Title, _Entity.SubseccionTRD.Title)); }
            if (_Entity.SubserieTRD != oldEntity.SubserieTRD) { changes.Append(LogPropertyChange("Subserie", oldEntity.SubserieTRD.Title, _Entity.SubserieTRD.Title)); }
            if (_Entity.TiempoDeRetenciónEnArchivoCentral != oldEntity.TiempoDeRetenciónEnArchivoCentral) { changes.Append(LogPropertyChange("Tiempo de Retención en el archivo central", oldEntity.TiempoDeRetenciónEnArchivoCentral, _Entity.TiempoDeRetenciónEnArchivoCentral)); }
            if (_Entity.TiempoDeRetenciónEnArchivoGeneral != oldEntity.TiempoDeRetenciónEnArchivoGeneral) { changes.Append(LogPropertyChange("Tiempo de Retención en el archivo general", oldEntity.TiempoDeRetenciónEnArchivoGeneral, _Entity.TiempoDeRetenciónEnArchivoGeneral)); }
            //if (_Entity.TiposDocumentales.Except(oldEntity.TiposDocumentales).Count() > 0) { changes.Append(LogPropertyChange("Tipos documental", oldEntity.TiempoDeRetenciónEnArchivoGeneral, _Entity.TiempoDeRetenciónEnArchivoGeneral)); }

            return changes.ToString();
        }

        private string LogPropertyChange(string propertyName, object oldValue, object newValue)
        {
            return string.Format("Cambio en la propiedad '{0}', de {1} a {2}.\n", propertyName, oldValue, newValue);
        }

        #endregion
    }
}
